using System;
using System.Collections.Generic;

namespace GatherTogether
{
    namespace GatherItems
    {
        /// <summary>
        /// A class which represents a specific zone within the game world. Stores a collection
        /// of nodes found within the zone.
        /// </summary>
        class Area : IEnumerable<Node>, IComparable<Area>
        {
            protected GatherConstants.MapZone m_mapZone = GatherConstants.MapZone.Unknown;
            protected List<Node> m_nodes = new List<Node>();

            /// <summary>
            /// Default constructor.
            /// </summary>
            public Area()
            {
            }

            /// <summary>
            /// A constructor which takes a string holding the name of the zone as an argument.
            /// </summary>
            /// <param name="areaName"></param>
            public Area(string areaName)
            {
                m_mapZone = GatherConstants.AreaName.GetZone(areaName);
            }

            public IEnumerator<Node> GetEnumerator()
            {
                foreach (Node node in m_nodes)
                {
                    yield return node;
                }
            }

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }

            public bool Equals(Area other)
            {
                return m_mapZone.Equals(other.m_mapZone);
            }

            public int CompareTo(Area other)
            {
                return m_mapZone.CompareTo(other.m_mapZone);
            }

            /// <summary>
            /// Accessor for the specific zone this area represents.
            /// </summary>
            public GatherConstants.MapZone Zone
            {
                get { return m_mapZone; }
                set { m_mapZone = value; }
            }

            /// <summary>
            /// Adds a gather node into the list for the area.
            /// </summary>
            /// <param name="node"></param>
            public void Add(Node node)
            {
                m_nodes.Add(node);
            }

            public void Merge(Area otherArea)
            {
                m_nodes.Sort();
                foreach (Node node in otherArea.m_nodes)
                {
                    int index = m_nodes.BinarySearch(node);

                    if (index < 0)
                    {
                        m_nodes.Add(node);
                    }
                    else
                    {
                        m_nodes[index].Merge(node);
                    }
                }
            }
        }
    }
}